﻿/******************************************************************************
 * Name         : Exception.hpp
 * Author       : 671643387
 * Date         : 2015年9月23日
 * Description  : 异常类
 *****************************************************************************/

#ifndef DEV_BASE_EXCEPTION_HPP_
#define DEV_BASE_EXCEPTION_HPP_

#include <exception>
#include <string>
#include <iostream>
#include <dev/Platform.hpp>
#include <dev/base/Console.hpp>

#if !defined(DEV_THROW)
#define DEV_THROW(ExClass, ...)                                  \
    do                                                           \
    {                                                            \
        ExClass e(__VA_ARGS__);                                  \
        e.init(__FILE__, __FUNCTION__, __LINE__);                \
        throw e;                                                 \
    } while (false);                                             \


#endif

#if !defined(DEV_NARGS_THROW)
#define DEV_NARGS_THROW(ExClass)                                 \
    do                                                           \
    {                                                            \
        ExClass e;                                               \
        e.init(__FILE__, __FUNCTION__, __LINE__);                \
        throw e;                                                 \
    } while (false);                                             \


#endif

namespace dev
{
    namespace base
    {
        /**
         * @berif 异常类
         */
        class Exception : public std::exception
        {
        public:
            Exception(void);
            explicit Exception(int code);
            explicit Exception(const char * const error);
            Exception(int code, const char * const error);
            Exception(const Exception& exception);
            virtual ~Exception(void);

            void init(const char* file, const char* function, int line);

#if defined(__WINDOWS__)
            /**
             * @brief 加载dbghelper
             * @return bool
             */
            static bool loadHelper(void);
#endif

        public:
            Exception& operator=(const Exception& exception);

        public:
            // override
            virtual const char* what(void) const DEV_NOEXCEPT { return error_.c_str(); }

        public:
            /**
             * @brief 获取错误码
             * @return int
             */
            int code(void) const { return code_; }

            /**
             * @brief 获取抛出异常的文件名
             * @return const char*
             */
            const char* file(void) const { return file_; }

            /**
             * @brief 获取抛出异常的函数名
             * @return const char*
             */
            const char* function(void) const { return function_; }

            /**
             * @brief 获取抛出异常的行号
             * @return int
             */
            int line(void) const { return line_; }

            /**
             * @brief 获取调用堆栈
             * @return const char*
             */
            const char* stacktrace(void) { return stackstrace_.c_str(); }

        protected:
            int code_;
            std::string error_;
            std::string stackstrace_;

            const char* file_;
            const char* function_;
            int line_;
        };

        /**
         * @brief 输出异常到输出流
         */
        std::ostream& operator<<(std::ostream& os, dev::base::Exception& e);
    }
}

#endif /* DEV_BASE_EXCEPTION_HPP_ */
